#include "boardpanel.h"
#include <iostream>
using namespace std;

const int BoardPanel::ID_PLAYER_VS_AI=230;
const int BoardPanel::ID_AI_VS_AI=231;
const int BoardPanel::ID_GREEDY_BY_FRONT=232;
const int BoardPanel::ID_GREEDY_BY_BACK=234;
const int BoardPanel::ID_SLOW=235;
const int BoardPanel::ID_MEDIUM=236;
const int BoardPanel::ID_FAST=237;

BoardPanel::BoardPanel(wxWindow*parent,int id,int boardsize,int gametype,int **arr,int greedytype,int greedytype1,int greedytype2,int gamespeed) : wxPanel(parent,id)
{
    this->gametype=gametype;
    this->greedytype=greedytype;
    this->greedytype1=greedytype1;
    this->greedytype2=greedytype2;
    this->gamespeed=gamespeed;

    cout << this->gametype << endl;
    cout << this->greedytype << endl;
    cout << this->greedytype1 << endl;
    cout << this->greedytype2 << endl;
    cout << this->gamespeed << endl;

    befpoint.x=0;
    befpoint.y=0;
    this->isplayerturn=true;
    this->boardsize=boardsize;
    this->arr=arr;

    wxGridSizer *gs = new wxGridSizer(boardsize,boardsize,5,5);
    int i,j;
    arrdam = (Dam**) malloc (boardsize*sizeof(Dam));
    for(i=0;i<boardsize;++i)
    {
        arrdam[i] = (Dam*)malloc(boardsize*sizeof(Dam));
    }

    this->SetFocus();

    for(i=0;i<boardsize;++i)
    {
        for(j=0;j<boardsize;++j)
        {
            Dam *dam = new Dam(this,arr[i][j],GetId(i,j,boardsize));
            (arrdam[i][j])=(*dam);
            gs->Add(arrdam[i][j].dambutton,0,wxEXPAND);
//            arrdam[i][j].dambutton->SetBitmapFocus(wxBitmap(wxT("source\\whitedam.png"),wxBITMAP_TYPE_PNG));
//            if (i==3)
//            {
//                wxPuts(wxT("3 3"));
//                arrdam[i][j].dambutton->SetBitmapLabel(wxBitmap(wxT("source\\whitedam.png"),wxBITMAP_TYPE_PNG));
//            }
//            wxPrintf(wxT("id %d,%d : %d,type : %d\n"),i,j,arrdam[i][j].ID_Dam,arrdam[i][j].type);
        }
    }
    this->SetSizer(gs);

    Connect(wxEVT_COMMAND_BUTTON_CLICKED,wxCommandEventHandler(BoardPanel::OnClickButton));
    solver = new Solver(boardsize);

    if (gametype==ID_AI_VS_AI)
    {
        StartAIVSAI();
    }
}

int BoardPanel::GetId(int x,int y,int bs)
{
    return (bs*x)+y;
}

wxPoint BoardPanel::GetPoint(int id,int bs)
{
    return wxPoint(id/bs,id%bs);
}

bool BoardPanel::IsWhite(int type)
{
    return type==Dam::ID_WHITE_DAM || type==Dam::ID_WHITE_KING_DAM;
}

void BoardPanel::OnClickButton(wxCommandEvent&event)
{
    wxPuts(wxT("Tombol dipencet"));
    wxPrintf(wxT("ID_Dam : %d\n"),event.GetId());
    if (isplayerturn)
    {
        wxPoint p=GetPoint(event.GetId(),boardsize);

        wxPrintf(wxT("befpoint x,y : %d,%d  ; p x,y : %d,%d\n"),befpoint.x,befpoint.y,p.x,p.y);

        if (arrdam[p.x][p.y].type==Dam::ID_BLACK_DAM || arrdam[p.x][p.y].type==Dam::ID_BLACK_KING_DAM)
        {
            befpoint=p;
            if (arrdam[p.x][p.y].type==Dam::ID_BLACK_DAM)
            {
                Refresher();
                arrdam[p.x][p.y].type=Dam::ID_BLACK_DAM_SELECTED;
                arrdam[p.x][p.y].ReType(arrdam[p.x][p.y].type);
                arr[p.x][p.y]=Dam::ID_BLACK_DAM_SELECTED;

                //gerakan kiri atas
                if (p.x>0 && p.y>0 && arrdam[p.x-1][p.y-1].type==Dam::ID_BLACK_EMPTY)
                {
                    arrdam[p.x-1][p.y-1].type=Dam::ID_BLACK_EMPTY_MOVE;
                    arrdam[p.x-1][p.y-1].ReType(arrdam[p.x-1][p.y-1].type);
                    arr[p.x-1][p.y-1]=Dam::ID_BLACK_EMPTY_MOVE;
                }
                //makan kiri atas
                if (p.x>1 && p.y>1 && IsWhite(arrdam[p.x-1][p.y-1].type) && arrdam[p.x-2][p.y-2].type==Dam::ID_BLACK_EMPTY)
                {
                    arrdam[p.x-2][p.y-2].type=Dam::ID_BLACK_EMPTY_MOVE;
                    arrdam[p.x-2][p.y-2].ReType(arrdam[p.x-2][p.y-2].type);
                    arr[p.x-2][p.y-2]=Dam::ID_BLACK_EMPTY_MOVE;
                }

                //gerakan kanan atas
                if (p.x>0 && p.y<boardsize-1 && arrdam[p.x-1][p.y+1].type==Dam::ID_BLACK_EMPTY)
                {
                    arrdam[p.x-1][p.y+1].type=Dam::ID_BLACK_EMPTY_MOVE;
                    arrdam[p.x-1][p.y+1].ReType(arrdam[p.x-1][p.y+1].type);
                    arr[p.x-1][p.y+1]=Dam::ID_BLACK_EMPTY_MOVE;
                }
                //gerakan makan kanan atas
                if (p.x>1 && p.y<boardsize-2 && IsWhite(arrdam[p.x-1][p.y+1].type) && arrdam[p.x-2][p.y+2].type==Dam::ID_BLACK_EMPTY)
                {
                    arrdam[p.x-2][p.y+2].type=Dam::ID_BLACK_EMPTY_MOVE;
                    arrdam[p.x-2][p.y+2].ReType(arrdam[p.x-2][p.y+2].type);
                    arr[p.x-2][p.y+2]=Dam::ID_BLACK_EMPTY_MOVE;
                }
            }
            else if(arrdam[p.x][p.y].type==Dam::ID_BLACK_KING_DAM)
            {
                Refresher();
                arrdam[p.x][p.y].type=Dam::ID_BLACK_KING_DAM_SELECTED;
                arrdam[p.x][p.y].ReType(arrdam[p.x][p.y].type);
                arr[p.x][p.y]=Dam::ID_BLACK_KING_DAM_SELECTED;

                //gerakan kiri atas
                if (p.x>0 && p.y>0 && arrdam[p.x-1][p.y-1].type==Dam::ID_BLACK_EMPTY)
                {
                    arrdam[p.x-1][p.y-1].type=Dam::ID_BLACK_EMPTY_MOVE;
                    arrdam[p.x-1][p.y-1].ReType(arrdam[p.x-1][p.y-1].type);
                    arr[p.x-1][p.y-1]=Dam::ID_BLACK_EMPTY_MOVE;
                }
                //makan kiri atas
                if (p.x>1 && p.y>1 && IsWhite(arrdam[p.x-1][p.y-1].type) && arrdam[p.x-2][p.y-2].type==Dam::ID_BLACK_EMPTY)
                {
                    arrdam[p.x-2][p.y-2].type=Dam::ID_BLACK_EMPTY_MOVE;
                    arrdam[p.x-2][p.y-2].ReType(arrdam[p.x-2][p.y-2].type);
                    arr[p.x-2][p.y-2]=Dam::ID_BLACK_EMPTY_MOVE;
                }

                //gerakan kanan atas
                if (p.x>0 && p.y<boardsize-1 && arrdam[p.x-1][p.y+1].type==Dam::ID_BLACK_EMPTY)
                {
                    arrdam[p.x-1][p.y+1].type=Dam::ID_BLACK_EMPTY_MOVE;
                    arrdam[p.x-1][p.y+1].ReType(arrdam[p.x-1][p.y+1].type);
                    arr[p.x-1][p.y+1]=Dam::ID_BLACK_EMPTY_MOVE;
                }
                //gerakan makan kanan atas
                if (p.x>1 && p.y<boardsize-2 && IsWhite(arrdam[p.x-1][p.y+1].type) && arrdam[p.x-2][p.y+2].type==Dam::ID_BLACK_EMPTY)
                {
                    arrdam[p.x-2][p.y+2].type=Dam::ID_BLACK_EMPTY_MOVE;
                    arrdam[p.x-2][p.y+2].ReType(arrdam[p.x-2][p.y+2].type);
                    arr[p.x-2][p.y+2]=Dam::ID_BLACK_EMPTY_MOVE;
                }

                //gerakan kiri bawah
                if (p.x<boardsize-1 && p.y>0 && arrdam[p.x+1][p.y-1].type==Dam::ID_BLACK_EMPTY)
                {
                    arrdam[p.x+1][p.y-1].type=Dam::ID_BLACK_EMPTY_MOVE;
                    arrdam[p.x+1][p.y-1].ReType(arrdam[p.x+1][p.y-1].type);
                    arr[p.x+1][p.y-1]=Dam::ID_BLACK_EMPTY_MOVE;
                }
                //makan kiri bawah
                if (p.x<boardsize-2 && p.y>1 && IsWhite(arrdam[p.x+1][p.y-1].type) && arrdam[p.x+2][p.y-2].type==Dam::ID_BLACK_EMPTY)
                {
                    arrdam[p.x+2][p.y-2].type=Dam::ID_BLACK_EMPTY_MOVE;
                    arrdam[p.x+2][p.y-2].ReType(arrdam[p.x+2][p.y-2].type);
                    arr[p.x+2][p.y-2]=Dam::ID_BLACK_EMPTY_MOVE;
                }

                //gerakan kanan bawah
                if (p.x<boardsize-1 && p.y<boardsize-1 && arrdam[p.x+1][p.y+1].type==Dam::ID_BLACK_EMPTY)
                {
                    arrdam[p.x+1][p.y+1].type=Dam::ID_BLACK_EMPTY_MOVE;
                    arrdam[p.x+1][p.y+1].ReType(arrdam[p.x+1][p.y+1].type);
                    arr[p.x+1][p.y+1]=Dam::ID_BLACK_EMPTY_MOVE;
                }
                //makan kanan bawah
                if (p.x<boardsize-2 && p.y<boardsize-2 && IsWhite(arrdam[p.x+1][p.y+1].type) && arrdam[p.x+2][p.y+2].type==Dam::ID_BLACK_EMPTY)
                {
                    arrdam[p.x+2][p.y+2].type=Dam::ID_BLACK_EMPTY_MOVE;
                    arrdam[p.x+2][p.y+2].ReType(arrdam[p.x+2][p.y+2].type);
                    arr[p.x+2][p.y+2]=Dam::ID_BLACK_EMPTY_MOVE;
                }

            }
        }
        else if (arrdam[p.x][p.y].type==Dam::ID_BLACK_EMPTY_MOVE)
        {
            wxPuts(wxT("makan atau bergerak\n"));
            if (abs(p.x-befpoint.x)==1 && abs(p.y-befpoint.y)==1)
            {
                wxPuts(wxT("hanya bergerak\n"));
                bool iscustom=(arrdam[befpoint.x][befpoint.y].type==Dam::ID_BLACK_DAM_SELECTED);
                arrdam[befpoint.x][befpoint.y].type=Dam::ID_BLACK_EMPTY;
                arrdam[befpoint.x][befpoint.y].ReType(arrdam[befpoint.x][befpoint.y].type);
                arr[befpoint.x][befpoint.y]=Dam::ID_BLACK_EMPTY;

                if (iscustom)
                {
                    arrdam[p.x][p.y].type=Dam::ID_BLACK_DAM;
                    arrdam[p.x][p.y].ReType(arrdam[p.x][p.y].type);
                    arr[p.x][p.y]=Dam::ID_BLACK_DAM;
                }
                if (!iscustom || p.x==0)
                {
                    arrdam[p.x][p.y].type=Dam::ID_BLACK_KING_DAM;
                    arrdam[p.x][p.y].ReType(arrdam[p.x][p.y].type);
                    arr[p.x][p.y]=Dam::ID_BLACK_KING_DAM;
                }

            }
            else if (abs(p.x-befpoint.x)==2 && abs(p.y-befpoint.y)==2)//eating procedure
            {
                wxPuts(wxT("hanya makan\n"));
                bool iscustom=(arrdam[befpoint.x][befpoint.y].type==Dam::ID_BLACK_DAM_SELECTED);
                arrdam[befpoint.x][befpoint.y].type=Dam::ID_BLACK_EMPTY;
                arrdam[befpoint.x][befpoint.y].ReType(arrdam[befpoint.x][befpoint.y].type);
                arr[befpoint.x][befpoint.y]=Dam::ID_BLACK_EMPTY;

                wxPoint mpoint = wxPoint((befpoint.x+p.x)/2,(befpoint.y+p.y)/2);
                arrdam[mpoint.x][mpoint.y].type=Dam::ID_BLACK_EMPTY;
                arrdam[mpoint.x][mpoint.y].ReType(arrdam[mpoint.x][mpoint.y].type);
                arr[mpoint.x][mpoint.y]=Dam::ID_BLACK_EMPTY;

                if (iscustom)
                {
                    arrdam[p.x][p.y].type=Dam::ID_BLACK_DAM;
                    arrdam[p.x][p.y].ReType(arrdam[p.x][p.y].type);
                    arr[p.x][p.y]=Dam::ID_BLACK_DAM;
                }
                if (!iscustom || p.x==0)
                {
                    arrdam[p.x][p.y].type=Dam::ID_BLACK_KING_DAM;
                    arrdam[p.x][p.y].ReType(arrdam[p.x][p.y].type);
                    arr[p.x][p.y]=Dam::ID_BLACK_KING_DAM;
                }
                wxPuts(wxT("makan\n"));
                wxPrintf(wxT("awal x,y : %d,%d   tengah x,y : %d,%d   akhir x,y : %d,%d\n"),befpoint.x,befpoint.y,mpoint.x,mpoint.y,p.x,p.y);
            }

            Refresher();
            wxThread::Sleep(1000);

            solver->setBoard(arr);

            int playerid=ID_PLAYER_PUTIH;
            bool isstillturn=true;
            int movetype=0;
            bool isgerak=true;

            solver->moveByGreedyTypeOne(playerid,boardsize,&isstillturn,&movetype,&isgerak);
//            void moveByGreedyTypeOne(int playerid,int size,bool* isstillturn,int* movetype,bool* isgerak);
            wxPoint source = solver->getSource();
            wxPoint dest = solver->getDest();

            cout << "source\n";
            cout << "x : " << source.x << ",y : " << source.y << endl;
            cout << "dest\n";
            cout << "x : " << dest.x << ",y : " << dest.y << endl;

            arrdam[source.x][source.y].type=Dam::ID_BLACK_EMPTY;
            arrdam[source.x][source.y].ReType(arrdam[source.x][source.y].type);
            arr[source.x][source.y]=Dam::ID_BLACK_EMPTY;

            arrdam[dest.x][dest.y].type=Dam::ID_WHITE_DAM;
            arrdam[dest.x][dest.y].ReType(arrdam[dest.x][dest.y].type);
            arr[dest.x][dest.y]=Dam::ID_WHITE_DAM;

        }
    }
}

void BoardPanel::Refresher()
{
    int i,j;
    for(i=0;i<boardsize;++i)
    {
        for(j=0;j<boardsize;++j)
        {
            if (arrdam[i][j].type==Dam::ID_BLACK_DAM_SELECTED)
            {
                arrdam[i][j].type=Dam::ID_BLACK_DAM;
                arr[i][j]=Dam::ID_BLACK_DAM;
                arrdam[i][j].ReType(arrdam[i][j].type);
            }
            else if (arrdam[i][j].type==Dam::ID_BLACK_KING_DAM_SELECTED)
            {
                arrdam[i][j].type=Dam::ID_BLACK_KING_DAM;
                arr[i][j]=Dam::ID_BLACK_KING_DAM;
                arrdam[i][j].ReType(arrdam[i][j].type);
            }
            else  if (arrdam[i][j].type==Dam::ID_BLACK_EMPTY_MOVE)
            {
                arrdam[i][j].type=Dam::ID_BLACK_EMPTY;
                arr[i][j]=Dam::ID_BLACK_EMPTY;
                arrdam[i][j].ReType(arrdam[i][j].type);
            }
        }
    }
}


void BoardPanel::StartAIVSAI()
{
    wxPuts(wxT("Start ai\n"));
}

